<template>
  <div class="app-container">
    <!-- 搜索区域 -->
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="人员" prop="userId">
        <el-select
          v-model="queryParams.userId"
          placeholder="请选择人员"
          clearable
          style="width: 240px"
        >
          <el-option
            v-for="item in userOptions"
            :key="item.userId"
            :label="item.userName"
            :value="item.userId"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="日期范围">
        <el-date-picker
          v-model="dateRange"
          style="width: 240px"
          value-format="yyyy-MM-dd"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        ></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        <el-button :icon="showSearch ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showSearch=!showSearch"></el-button>
      </el-form-item>
    </el-form>

    <!-- 统计卡片区域 -->
    <el-row :gutter="20">
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>正常打卡</span>
            <el-tooltip content="按时签到签退" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.normalDays || 0 }}</div>
            <div class="card-item-text">天</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>迟到</span>
            <el-tooltip content="签到时间晚于规定时间" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.lateDays || 0 }}</div>
            <div class="card-item-text">天</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>早退</span>
            <el-tooltip content="签退时间早于规定时间" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.earlyDays || 0 }}</div>
            <div class="card-item-text">天</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>缺勤</span>
            <el-tooltip content="未打卡或未签退(不含请假)" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.adjustedAbsentDays !== undefined ? stats.adjustedAbsentDays : stats.absentDays || 0 }}</div>
            <div class="card-item-text">天</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>补卡</span>
            <el-tooltip content="已审批通过的补签到或补签退申请" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.reapplyDays || 0 }}</div>
            <div class="card-item-text">次</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="4">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>请假</span>
            <el-tooltip content="已审批通过的请假申请" placement="top">
              <i class="el-icon-question" style="margin-left: 5px"></i>
            </el-tooltip>
          </div>
          <div class="card-item">
            <div class="card-item-number">{{ stats.leaveDays || 0 }}</div>
            <div class="card-item-text">天</div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 图表统计区域 -->
    <el-row :gutter="20" style="margin-top: 20px;">
      <el-col :span="12">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>打卡趋势</span>
            <div class="card-header-right">
              <el-radio-group v-model="chartTimeType" size="mini" @change="handleChartTimeChange">
                <el-radio-button label="week">本周</el-radio-button>
                <el-radio-button label="month">本月</el-radio-button>
              </el-radio-group>
            </div>
          </div>
          <div class="chart-container">
            <div ref="attendanceChart" style="height: 300px;"></div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card class="box-card" shadow="hover">
          <div slot="header" class="clearfix">
            <span>打卡类型分布</span>
          </div>
          <div class="chart-container">
            <div ref="pieChart" style="height: 300px;"></div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 打卡记录表格 -->
    <el-card class="box-card" style="margin-top: 20px;" shadow="hover">
      <div slot="header" class="clearfix">
        <span>打卡记录详情</span>
        <div class="card-header-right">
          <el-button
            type="success"
            icon="el-icon-download"
            size="mini"
            @click="handleExport"
            v-hasPermi="['system:attendance:export']"
          >导出</el-button>
        </div>
      </div>
      <el-table
        v-loading="loading"
        :data="attendanceList"
        border
        stripe
        style="width: 100%"
      >
        <el-table-column label="序号" type="index" width="50" align="center" />
        <el-table-column label="部门" align="center" prop="deptName" />
        <el-table-column label="人员" align="center" prop="userName" />
        <el-table-column label="打卡日期" align="center" prop="attendanceDate" width="100">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.attendanceDate, '{y}-{m}-{d}') }}</span>
          </template>
        </el-table-column>
        <el-table-column label="签到时间" align="center" prop="clockInTime">
          <template slot-scope="scope">
            <span :class="{'text-warning': scope.row.isLate === '1'}">
              <template v-if="scope.row.status === 'R' && scope.row.reapplyInfo && scope.row.reapplyInfo.reapplyType === 'in'">
                {{ scope.row.reapplyInfo.reapplyTime }}
                <el-tag size="mini" type="warning">补卡</el-tag>
              </template>
              <template v-else>
                {{ scope.row.clockInTime }}
              </template>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="签到地点" align="center" prop="clockInLocation" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span v-if="scope.row.status === 'R' && scope.row.reapplyInfo && scope.row.reapplyInfo.reapplyType === 'in'">
              {{ scope.row.reapplyInfo.reapplyLocation }}
            </span>
            <span v-else>{{ scope.row.clockInLocation }}</span>
          </template>
        </el-table-column>
        <el-table-column label="签退时间" align="center" prop="clockOutTime">
          <template slot-scope="scope">
            <span :class="{'text-warning': scope.row.isEarly === '1'}">
              <template v-if="scope.row.status === 'R' && scope.row.reapplyInfo && scope.row.reapplyInfo.reapplyType === 'out'">
                {{ scope.row.reapplyInfo.reapplyTime }}
                <el-tag size="mini" type="warning">补卡</el-tag>
              </template>
              <template v-else>
                {{ scope.row.clockOutTime }}
              </template>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="签退地点" align="center" prop="clockOutLocation" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span v-if="scope.row.status === 'R' && scope.row.reapplyInfo && scope.row.reapplyInfo.reapplyType === 'out'">
              {{ scope.row.reapplyInfo.reapplyLocation }}
            </span>
            <span v-else>{{ scope.row.clockOutLocation }}</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="status">
          <template slot-scope="scope">
            <template v-if="scope.row.status === 'L'">
              <el-tag type="info" size="mini">请假</el-tag>
            </template>
            <template v-else-if="scope.row.status === 'R'">
              <el-tag type="warning" size="mini">
                补卡{{ scope.row.reapplyInfo ? (scope.row.reapplyInfo.reapplyType === 'in' ? '(签到)' : '(签退)') : '' }}
              </el-tag>
            </template>
            <template v-else>
              <dict-tag :options="dict.type.sys_attendance_status" :value="scope.row.status"/>
            </template>
          </template>
        </el-table-column>
        <el-table-column label="申请原因" align="center" prop="reason" :show-overflow-tooltip="true">
          <template slot-scope="scope">
            <span v-if="scope.row.status === 'R' && scope.row.reapplyInfo">
              {{ scope.row.reapplyInfo.reason }}
            </span>
            <span v-else-if="scope.row.status === 'L' && scope.row.leaveInfo">
              {{ scope.row.leaveInfo.reason }}
            </span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
      </el-table>
      <pagination
        v-show="total>0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>
  </div>
</template>

<script>
import { listAttendance, getAttendanceStats, getAttendanceChartData, listReapply, listLeave } from "@/api/system/attendance";
import { parseTime, addDateRange } from '@/utils/ruoyi';
import { listUser } from "@/api/system/user";
import * as echarts from 'echarts';

export default {
  name: "AttendanceReport",
  dicts: ['sys_attendance_status'],
  data() {
    return {
      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 员工打卡记录表格数据
      attendanceList: [],
      // 统计数据
      stats: {},
      // 用户选项
      userOptions: [],
      // 日期范围
      dateRange: [],
      // 图表时间类型
      chartTimeType: 'week',
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userId: null,
        attendanceDate: null,
        status: null
      },
      // 图表实例
      attendanceChart: null,
      pieChart: null
    };
  },
  created() {
    this.getUsers();
    this.getStats();
    this.getList();
  },
  mounted() {
    this.$nextTick(() => {
      this.initCharts();
    });
    window.addEventListener('resize', this.resizeCharts);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeCharts);
    if (this.attendanceChart) {
      this.attendanceChart.dispose();
    }
    if (this.pieChart) {
      this.pieChart.dispose();
    }
  },
  methods: {
    /** 查询用户列表 */
    getUsers() {
      listUser().then(response => {
        this.userOptions = response.rows;
      });
    },
    /** 查询打卡统计数据 */
    getStats() {
      const params = this.addDateRange({
        userId: this.queryParams.userId ? this.queryParams.userId.toString() : null
      }, this.dateRange);
      
      getAttendanceStats(params).then(response => {
        this.stats = response.data || {};
        
        // 获取补卡和请假记录数量
        this.getReapplyAndLeaveStats(params).then(extraStats => {
          // 合并统计数据
          this.stats = {
            ...this.stats,
            ...extraStats
          };
          this.updatePieChart();
        }).catch(error => {
          console.error("获取补卡和请假统计失败:", error);
          this.updatePieChart();
        });
      });
    },
    
    /** 获取补卡和请假统计数据 */
    getReapplyAndLeaveStats(params) {
      return new Promise((resolve, reject) => {
        // 创建统计对象
        const extraStats = {
          reapplyDays: 0,
          leaveDays: 0,
          adjustedAbsentDays: 0  // 调整后的缺勤天数
        };
        
        // 获取补卡申请记录
        listReapply(params).then(reapplyResponse => {
          const reapplyData = reapplyResponse.rows || [];
          // 只计算已审批通过的补卡次数
          extraStats.reapplyDays = reapplyData.filter(item => item.status === '1').length;
          
          // 获取请假申请记录
          listLeave(params).then(leaveResponse => {
            const leaveData = leaveResponse.rows || [];
            
            // 计算请假天数和请假日期集合
            let leaveDates = new Set();
            
            if (leaveData.length > 0) {
              // 只计算已审批通过的请假记录
              const approvedLeaves = leaveData.filter(item => item.status === '1');
              
              // 累计请假天数（可以根据实际需求调整计算逻辑）
              extraStats.leaveDays = approvedLeaves.reduce((total, item) => {
                // 计算请假天数（结束日期 - 开始日期）
                const startDate = new Date(item.startTime);
                const endDate = new Date(item.endTime);
                const diffTime = Math.abs(endDate - startDate);
                const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
                
                // 记录请假的具体日期
                for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
                  leaveDates.add(this.formatDate(date));
                }
                
                return total + (diffDays || 1); // 至少算1天
              }, 0);
            }
            
            // 调整缺勤天数 = 原缺勤天数 - 请假天数中的工作日
            // 首先获取原缺勤天数
            if (this.stats && typeof this.stats.absentDays !== 'undefined') {
              // 获取工作日期范围
              const workdayRange = this.getWorkdayRange(params);
              
              // 计算请假日中的工作日数量
              let leaveWorkdays = 0;
              workdayRange.forEach(date => {
                if (leaveDates.has(date)) {
                  leaveWorkdays++;
                }
              });
              
              // 调整缺勤天数 = 原缺勤天数 - 请假工作日数量
              // 确保不会出现负数
              extraStats.adjustedAbsentDays = Math.max(0, this.stats.absentDays - leaveWorkdays);
            }
            
            resolve(extraStats);
          }).catch(error => {
            console.error("获取请假申请记录失败:", error);
            resolve(extraStats);
          });
        }).catch(error => {
          console.error("获取补卡申请记录失败:", error);
          resolve(extraStats);
        });
      });
    },
    
    /** 获取工作日期范围 */
    getWorkdayRange(params) {
      // 如果有日期范围参数，使用参数中的日期范围
      let startDate, endDate;
      if (params.beginTime && params.endTime) {
        startDate = new Date(params.beginTime);
        endDate = new Date(params.endTime);
      } else if (this.dateRange && this.dateRange.length === 2) {
        startDate = new Date(this.dateRange[0]);
        endDate = new Date(this.dateRange[1]);
      } else {
        // 默认使用当前月
        const now = new Date();
        startDate = new Date(now.getFullYear(), now.getMonth(), 1);
        endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0);
      }
      
      // 生成日期范围内的所有日期
      const dateRange = [];
      for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
        dateRange.push(this.formatDate(date));
      }
      
      return dateRange;
    },
    /** 查询员工打卡记录列表 */
    getList() {
      this.loading = true;
      const params = this.addDateRange({
        ...this.queryParams,
        userId: this.queryParams.userId ? this.queryParams.userId.toString() : null
      }, this.dateRange);

      // 获取普通考勤记录
      listAttendance(params).then(response => {
        let attendanceData = response.rows || [];
        
        // 获取补卡和请假记录
        this.getReapplyAndLeaveRecords(params, attendanceData).then(combinedData => {
          this.attendanceList = combinedData;
          this.total = combinedData.length;
          this.loading = false;
        }).catch(error => {
          console.error("获取补卡和请假记录失败:", error);
          this.attendanceList = attendanceData;
          this.total = attendanceData.length;
          this.loading = false;
        });
      }).catch(() => {
        this.loading = false;
      });
    },
    
    /** 获取补卡和请假记录 */
    getReapplyAndLeaveRecords(params, attendanceData) {
      return new Promise((resolve, reject) => {
        // 获取补卡申请记录
        listReapply(params).then(reapplyResponse => {
          const reapplyData = reapplyResponse.rows || [];
          
          // 只处理已审批通过的补卡记录
          const approvedReapplies = reapplyData.filter(item => item.status === '1');
          
          // 将补卡申请转换为考勤记录格式，并添加到列表中
          approvedReapplies.forEach(item => {
            // 检查是否已存在相同日期的考勤记录
            const existingIndex = attendanceData.findIndex(a => 
              a.userId === item.userId && 
              this.formatDate(a.attendanceDate) === this.formatDate(item.attendanceDate)
            );
            
            if (existingIndex === -1) {
              // 如果不存在，创建一条新记录
              attendanceData.push({
                attendanceId: 'R' + item.reapplyId, // 添加前缀以区分
                userId: item.userId,
                userName: item.userName,
                deptName: item.deptName,
                attendanceDate: item.attendanceDate,
                status: 'R',
                remark: item.reason,
                reapplyInfo: item // 保存原始补卡信息
              });
            } else {
              // 如果存在，添加补卡信息
              attendanceData[existingIndex].reapplyInfo = item;
              attendanceData[existingIndex].status = 'R';
            }
          });
          
          // 获取请假申请记录
          listLeave(params).then(leaveResponse => {
            const leaveData = leaveResponse.rows || [];
            
            // 只处理已审批通过的请假记录
            const approvedLeaves = leaveData.filter(item => item.status === '1');
            
            // 将请假申请转换为考勤记录格式，并添加到列表中
            approvedLeaves.forEach(item => {
              // 将请假开始日期转换为日期对象
              const leaveStartDate = new Date(item.startTime);
              const formattedStartDate = `${leaveStartDate.getFullYear()}-${String(leaveStartDate.getMonth() + 1).padStart(2, '0')}-${String(leaveStartDate.getDate()).padStart(2, '0')}`;
              
              // 检查是否已存在相同日期的考勤记录
              const existingIndex = attendanceData.findIndex(a => 
                a.userId === item.userId && 
                this.formatDate(a.attendanceDate) === formattedStartDate
              );
              
              if (existingIndex === -1) {
                // 如果不存在，创建一条新记录
                attendanceData.push({
                  attendanceId: 'L' + item.leaveId, // 添加前缀以区分
                  userId: item.userId,
                  userName: item.userName,
                  deptName: item.deptName,
                  attendanceDate: formattedStartDate,
                  status: 'L',
                  remark: item.reason,
                  leaveInfo: item // 保存原始请假信息
                });
              } else {
                // 如果存在，添加请假信息
                attendanceData[existingIndex].leaveInfo = item;
                attendanceData[existingIndex].status = 'L';
              }
            });
            
            resolve(attendanceData);
          }).catch(error => {
            console.error("获取请假申请记录失败:", error);
            // 即使请假记录获取失败，也返回已有记录
            resolve(attendanceData);
          });
        }).catch(error => {
          console.error("获取补卡申请记录失败:", error);
          // 即使补卡记录获取失败，也返回考勤记录
          resolve(attendanceData);
        });
      });
    },
    
    /** 格式化日期，仅保留年月日 */
    formatDate(dateStr) {
      if (!dateStr) return '';
      const date = new Date(dateStr);
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getStats();
      this.getList();
      this.getChartData();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.queryParams.userId = null;
      this.handleQuery();
    },
    // 表单重置
    resetForm(refName) {
      if (this.$refs[refName]) {
        this.$refs[refName].resetFields();
      }
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/attendance/export', {
        ...this.queryParams,
        ...this.addDateRange({}, this.dateRange)
      }, `考勤统计_${new Date().getTime()}.xlsx`);
    },
    /** 图表时间类型变更 */
    handleChartTimeChange() {
      this.getChartData();
    },
    /** 获取图表数据 */
    getChartData() {
      const params = {
        timeType: this.chartTimeType,
        userId: this.queryParams.userId ? this.queryParams.userId.toString() : null,
        ...this.addDateRange({}, this.dateRange)
      };
      
      getAttendanceChartData(params).then(response => {
        const data = response.data || {};
        
        // 获取图表的补卡和请假数据
        this.getReapplyAndLeaveChartData(params, data).then(updatedData => {
          this.updateAttendanceChart(updatedData);
        }).catch(error => {
          console.error("获取补卡和请假图表数据失败:", error);
          this.updateAttendanceChart(data);
        });
      });
    },
    
    /** 获取补卡和请假图表数据 */
    getReapplyAndLeaveChartData(params, chartData) {
      return new Promise((resolve, reject) => {
        // 确保图表数据包含必要的属性
        if (!chartData.dates) {
          chartData.dates = [];
        }
        
        // 初始化补卡和请假数据数组
        chartData.reapply = Array(chartData.dates.length).fill(0);
        chartData.leave = Array(chartData.dates.length).fill(0);
        
        // 保存原始缺勤数据
        const originalAbsent = [...(chartData.absent || Array(chartData.dates.length).fill(0))];
        
        // 获取补卡申请记录
        listReapply(params).then(reapplyResponse => {
          const reapplyData = reapplyResponse.rows || [];
          
          // 只处理已审批通过的补卡数据
          const approvedReapplies = reapplyData.filter(item => item.status === '1');
          
          // 处理补卡数据
          approvedReapplies.forEach(item => {
            const itemDate = this.formatDate(item.attendanceDate);
            const dateIndex = chartData.dates.findIndex(date => date === itemDate);
            if (dateIndex !== -1) {
              chartData.reapply[dateIndex]++;
            }
          });
          
          // 获取请假申请记录
          listLeave(params).then(leaveResponse => {
            const leaveData = leaveResponse.rows || [];
            
            // 只处理已审批通过的请假数据
            const approvedLeaves = leaveData.filter(item => item.status === '1');
            
            // 处理请假数据
            approvedLeaves.forEach(item => {
              const startDate = new Date(item.startTime);
              const endDate = new Date(item.endTime);
              
              // 计算请假跨越的所有日期
              for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
                const itemDate = this.formatDate(date);
                const dateIndex = chartData.dates.findIndex(d => d === itemDate);
                if (dateIndex !== -1) {
                  chartData.leave[dateIndex]++;
                  
                  // 调整缺勤数据：如果当天有请假记录，则减少缺勤计数
                  if (chartData.absent && chartData.absent[dateIndex] > 0) {
                    chartData.absent[dateIndex]--;
                  }
                }
              }
            });
            
            resolve(chartData);
          }).catch(error => {
            console.error("获取请假申请记录失败:", error);
            resolve(chartData);
          });
        }).catch(error => {
          console.error("获取补卡申请记录失败:", error);
          resolve(chartData);
        });
      });
    },
    /** 初始化图表 */
    initCharts() {
      this.attendanceChart = echarts.init(this.$refs.attendanceChart);
      this.pieChart = echarts.init(this.$refs.pieChart);
      this.getChartData();
    },
    /** 更新打卡趋势图表 */
    updateAttendanceChart(data) {
      const option = {
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          data: ['正常', '迟到', '早退', '缺勤', '补卡', '请假']
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: data.dates || []
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            name: '正常',
            type: 'line',
            stack: '总量',
            data: data.normal || [],
            itemStyle: {
              color: '#67C23A'
            }
          },
          {
            name: '迟到',
            type: 'line',
            stack: '总量',
            data: data.late || [],
            itemStyle: {
              color: '#E6A23C'
            }
          },
          {
            name: '早退',
            type: 'line',
            stack: '总量',
            data: data.early || [],
            itemStyle: {
              color: '#F56C6C'
            }
          },
          {
            name: '缺勤',
            type: 'line',
            stack: '总量',
            data: data.absent || [],
            itemStyle: {
              color: '#909399'
            }
          },
          {
            name: '补卡',
            type: 'line',
            stack: '总量',
            data: data.reapply || [],
            itemStyle: {
              color: '#409EFF'
            }
          },
          {
            name: '请假',
            type: 'line',
            stack: '总量',
            data: data.leave || [],
            itemStyle: {
              color: '#9966CC'
            }
          }
        ]
      };
      this.attendanceChart.setOption(option);
    },
    /** 更新饼图 */
    updatePieChart() {
      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 10,
          data: ['正常打卡', '迟到', '早退', '缺勤', '补卡', '请假']
        },
        series: [
          {
            name: '打卡统计',
            type: 'pie',
            radius: ['50%', '70%'],
            avoidLabelOverlap: false,
            label: {
              show: false,
              position: 'center'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '18',
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            data: [
              { value: this.stats.normalDays || 0, name: '正常打卡', itemStyle: { color: '#67C23A' } },
              { value: this.stats.lateDays || 0, name: '迟到', itemStyle: { color: '#E6A23C' } },
              { value: this.stats.earlyDays || 0, name: '早退', itemStyle: { color: '#F56C6C' } },
              { value: this.stats.adjustedAbsentDays !== undefined ? this.stats.adjustedAbsentDays : this.stats.absentDays || 0, name: '缺勤', itemStyle: { color: '#909399' } },
              { value: this.stats.reapplyDays || 0, name: '补卡', itemStyle: { color: '#409EFF' } },
              { value: this.stats.leaveDays || 0, name: '请假', itemStyle: { color: '#9966CC' } }
            ]
          }
        ]
      };
      this.pieChart.setOption(option);
    },
    /** 响应窗口大小变化 */
    resizeCharts() {
      if (this.attendanceChart) {
        this.attendanceChart.resize();
      }
      if (this.pieChart) {
        this.pieChart.resize();
      }
    },
    // 添加日期范围
    addDateRange(params, dateRange) {
      return addDateRange(params, dateRange);
    },
    // 解析时间
    parseTime(time, pattern) {
      return parseTime(time, pattern);
    }
  }
};
</script>

<style scoped>
.card-item {
  text-align: center;
  padding: 20px 0;
}
.card-item-number {
  font-size: 36px;
  font-weight: bold;
  color: #409EFF;
}
.card-item-text {
  margin-top: 10px;
  font-size: 14px;
  color: #606266;
}
.card-header-right {
  float: right;
}
.chart-container {
  position: relative;
  width: 100%;
}
.text-warning {
  color: #E6A23C;
}
</style> 